package com.crm.redis.mapper;

import com.crm.common.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
public class HashRMapper {

	
	/**
	 * 根据key和hashkey获取一个值，并转化为castToClass所对应的类型
	 * 
	 * @param redisTemplate
	 * @param key
	 * @param castToClass
	 * @param               <T>
	 * @return
	 */
	public static <T> T getObject(RedisTemplate<String, Object> redisTemplate, String key, Class<T> castToClass) {
		if (key == null) {
			return null;
		} else {
			try {
				if (!StringUtils.isBlank(key)) {
					Map<Object, Object> objectMap = redisTemplate.opsForHash().entries(key);
					if (objectMap != null && !objectMap.isEmpty()) {
						Object object = ObjectUtil.mapToObject(objectMap, castToClass);
						return (T) object;
					}
				} else {
					return null;
				}
			} catch (Exception e) {
				log.error("R_HashRedisMapper getObject ERROR:", e);
				log.error("Data  key:" + key);
				return null;
			}
		}
		return null;
	}

	/**
	 * 根据key和hashkey获取一个值，并转化为castToClass所对应的类型
	 * 
	 * @param redisTemplate
	 * @param key
	 * @param hashKey
	 * @param castToClass
	 * @param               <T>
	 * @return
	 */
	public static <T> T getHashValue(RedisTemplate<String, Object> redisTemplate, String key, String hashKey,
			Class<T> castToClass) {
		if (key == null) {
			return null;
		}
		try {
			Object valueObj = redisTemplate.opsForHash().get(key, hashKey);
			if (valueObj != null && Integer.class.equals(valueObj.getClass())
					&& Long.class.equals(castToClass.getClass())) {
				// 如果是在获取一个0,手动给它一个0
				valueObj = new Long(0);
			}
			return (T) valueObj;
		} catch (Exception e) {
			log.error("R_HashRedisMapper getHashValue ERROR:", e);
			log.error("Data  key:" + key + ";hashKey:" + hashKey);
			throw e;
		}
	}


	/**
	 * 根据key和hashkey更新一个值
	 *
	 * @param redisTemplate
	 * @param key
	 * @param hashKey
	 * @param value
	 * @return
	 */
	public static Boolean putHashValue(RedisTemplate<String, Object> redisTemplate, String key, String hashKey,
			Object value) {
		Boolean resultBoolean = false;
		if (key == null || value == null) {

		} else {
			try {
				redisTemplate.opsForHash().put(key, hashKey, value);
				resultBoolean = true;
			} catch (Exception e) {
				log.error("R_HashRedisMapper putHashValue ERROR:", e);
				log.error("Data  key:" + key + ";hashKey:" + hashKey + ";value:" + value);
				throw e;
			}
		}
		return resultBoolean;
	}

	/**
	 * 根据key直接更新一个对象所有的属性到redis
	 *
	 * @param redisTemplate
	 * @param key
	 * @param object
	 * @return
	 */
	public static Boolean putObject(RedisTemplate<String, Object> redisTemplate, String key, Object object) {
		Boolean result = false;
		try {
			Map<String, Object> map = ObjectUtil.objectToMap(object);
			redisTemplate.opsForHash().putAll(key, map);
			result = true;
		} catch (Exception e) {
			log.error("R_HashRedisMapper putObject error:", e);
			log.error("Key :" + key);
		}
		return result;
	}

	/**
	 * 删除key对应的hashkey对应的键值对
	 *
	 * @param redisTemplate
	 * @param key
	 * @param hashKey
	 * @return
	 */
	public static Boolean delRedisHash(RedisTemplate<String, Object> redisTemplate, String key, String hashKey) {
		Boolean result = false;
		if (StringUtils.isBlank(key) == false) {
			try {
				redisTemplate.opsForHash().delete(key, hashKey);
				result = true;
			} catch (Exception e) {
				log.error("R_HashRedisMapper delRedisHash ERROR:", e);
				log.error("Data  key:" + key + ";hashKey:" + hashKey);
			}
		}
		return result;
	}

	/**
	 * 删除key对应的缓存
	 *
	 * @param redisTemplate
	 * @param key
	 * @return
	 */
	public static Boolean delRedis(RedisTemplate<String, Object> redisTemplate, String key) {
		Boolean result = false;
		if (StringUtils.isBlank(key) == false) {
			try {
				redisTemplate.delete(key);
				result = true;
			} catch (Exception e) {
				log.error("R_HashRedisMapper delRedis ERROR:", e);
				log.error("Data:" + key);
			}
		}
		return result;
	}

	/**
	 * 批量删除keys列表中key对应的缓存
	 *
	 * @param redisTemplate
	 * @param keys
	 * @return
	 */
	public static Boolean delRedisList(RedisTemplate<String, Object> redisTemplate, List<String> keys) {
		if (keys.size() == 0) {
			return false;
		}
		try {
			redisTemplate.delete(keys);
			return true;
		} catch (Exception e) {
			log.error("R_HashRedisMapper delRedisList ERROR:", e);
			log.error("Data:" + keys);
			throw e;
		}
	}

	/**
	 * 为redis中的某个key对应的缓存设置过期时间
	 *
	 * @param redisTemplate
	 * @param key
	 * @param timeout       过期时间数值
	 * @param timeunit      过期时间单位
	 * @return
	 */
	public static Boolean setRedisTimeout(RedisTemplate<String, Object> redisTemplate, String key, long timeout,
			TimeUnit timeunit) {
		Boolean result = false;
		if (key != null) {
			try {
				if (timeout == 0) {
					redisTemplate.delete(key);
				} else {
					redisTemplate.expire(key, timeout, timeunit);
				}
				result = true;
			} catch (Exception e) {
				log.error("R_ValueRedisMapper setRedisTimeout ERROR:", e);
				log.error("Data:" + key);
			}
		}
		return result;
	}
	
	/**
	 * 根据key获取下面所有的信息
	 * @param redisTemplate
	 * @param key
	 * @param map
	 * @return
	 */
	public static <K, V> Map<K, V> getAllRecord(RedisTemplate<String, Object> redisTemplate, String key,
			Map<K, V> map) {
		map = null;
		if (key != null) {
			try {
				if (redisTemplate.hasKey(key)) {
					Map<Object, Object> objectMap = redisTemplate.opsForHash().entries(key);
					if (objectMap != null && objectMap.size() > 0) {
                        map = (Map<K, V>) objectMap;
                    }
				}

			} catch (Exception e) {
				log.error("R_HashRedisMapper getObject ERROR:", e);
				log.error("Data  key:" + key);
			}
		}
		return map;
	}
	
	/**
	 * 根据key直接缓存一个map
	 * @param redisTemplate
	 * @param key
	 * @param recordMap
	 * @return
	 */
	public static <K, V> Boolean putAllRecord(RedisTemplate<String, Object> redisTemplate, String key, Map<K, V> recordMap) {
		Boolean result = false;
		try {
			redisTemplate.opsForHash().putAll(key, recordMap);
			result = true;
		} catch (Exception e) {
			log.error("R_HashRedisMapper putObject error:", e);
			log.error("Key :" + key);
		}
		return result;
	}
}
